package com.ltkj.baseplatform.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.nacos.shaded.com.google.gson.Gson;
import com.aliyun.dysmsapi20170525.models.SendBatchSmsResponse;
import com.aliyun.dysmsapi20170525.models.SendSmsResponse;
import com.aliyun.tea.TeaException;
import com.ltkj.common.core.web.domain.AjaxResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Component;

/**
 * 阿里云发送短信工具
 * @author xupf
 * @date 2023/10/07 14:24
 */
@Component
@RefreshScope
public class SendSmsAliUtil {
    private static final Logger log = LoggerFactory.getLogger(SendSmsAliUtil.class);

    @Value("${alibaba.sing-name-1}")
    private String defaultSignName;
    @Value("${alibaba.access-key.id}")
    private String alibabaCloudAccessKeyId;
    @Value("${alibaba.access-key.secret}")
    private String alibabaCloudAccessKeySecret;

    /**
     * 使用AK&SK初始化账号Client
     * @param accessKeyId
     * @param accessKeySecret
     * @return Client
     * @throws Exception
     */
    public static com.aliyun.dysmsapi20170525.Client createClient(String accessKeyId, String accessKeySecret) throws Exception {
        com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config()
                // 必填，您的 AccessKey ID
                .setAccessKeyId(accessKeyId)
                // 必填，您的 AccessKey Secret
                .setAccessKeySecret(accessKeySecret);
        // Endpoint 请参考 https://api.aliyun.com/product/Dysmsapi
        config.endpoint = "dysmsapi.aliyuncs.com";
        return new com.aliyun.dysmsapi20170525.Client(config);
    }


    /**
     * 发送短信接口
     *  验证码类型短信，建议使用此接口
     *  主要适用于短信单发场景，特殊场景下可支持群发（最多可向1000个手机号码发送同样内容的短信），但群发会有一定延迟。
     * @param tempCode     短信模板CODE
     * @param tempParams   短信模板变量对应的实际值，eg：{"code":"1234"}
     * @param phoneNumbers 接收短信的手机号码，多个用英文逗号隔开
     * @return AjaxResult
     */
    public AjaxResult sendSms(String tempCode, String tempParams, String phoneNumbers) {
        return sendSms(tempCode, tempParams, phoneNumbers, defaultSignName);
    }

    /**
     * 发送短信接口
     *  验证码类型短信，建议使用此接口
     *  主要适用于短信单发场景，特殊场景下可支持群发（最多可向1000个手机号码发送同样内容的短信），但群发会有一定延迟。
     * @param tempCode     短信模板CODE
     * @param tempParams   短信模板变量对应的实际值，eg：{"code":"1234"}
     * @param phoneNumbers 接收短信的手机号码，多个用英文逗号隔开
     * @param signName 签名，非必传
     * @return AjaxResult
     */
    public AjaxResult sendSms(String tempCode, String tempParams, String phoneNumbers, String signName) {
        // 请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_ID 和 ALIBABA_CLOUD_ACCESS_KEY_SECRET。
        // 工程代码泄露可能会导致 AccessKey 泄露，并威胁账号下所有资源的安全性。以下代码示例使用环境变量获取 AccessKey 的方式进行调用，仅供参考，建议使用更安全的 STS 方式，更多鉴权访问方式请参见：https://help.aliyun.com/document_detail/378657.html
        /*
         * Linux:
         * export ALIBABA_CLOUD_ACCESS_KEY_ID=<access_key_id>
         * export ALIBABA_CLOUD_ACCESS_KEY_SECRET=<access_key_secret>
         * Win:
         * 新建环境变量文件，添加环境变量 ALIBABA_CLOUD_ACCESS_KEY_ID 和 ALIBABA_CLOUD_ACCESS_KEY_SECRET ，并写入已准备好的AccessKey ID和AccessKey Secret。
         * 重启win
         */

        SendSmsResponse sendSmsResponse;
        try {
//          com.aliyun.dysmsapi20170525.Client client = createClient(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"), System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
            // 使用配置文件保存 id 和 Secret
            com.aliyun.dysmsapi20170525.Client client = createClient(alibabaCloudAccessKeyId, alibabaCloudAccessKeySecret);
            com.aliyun.dysmsapi20170525.models.SendSmsRequest sendSmsRequest = new com.aliyun.dysmsapi20170525.models.SendSmsRequest();
            // 接收短信的手机号码，多个用英文逗号隔开
            sendSmsRequest.setPhoneNumbers(phoneNumbers);
            // 短信签名名称，eg: "阿里云"
            sendSmsRequest.setSignName(signName);
//            sendSmsRequest.setSignName("石家庄滹沱河艺术生态岛");
            // 短信模板CODE
            sendSmsRequest.setTemplateCode(tempCode);
            // 短信模板变量对应的实际值，eg：{"code":"1234"}
            sendSmsRequest.setTemplateParam(tempParams);
            com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
//            log.info("调用发送短信接口请求参数：[模板code：{}，参数：{}，接收手机号：{}，签名：{}]", tempCode, tempParams, phoneNumbers, signName);
            log.info("调用发送短信接口请求参数：{}", JSON.toJSONString(sendSmsRequest));
            // 复制代码运行请自行打印 API 的返回值
            sendSmsResponse = client.sendSmsWithOptions(sendSmsRequest, runtime);
            log.info("调用发送短信接口返回结果：{}", JSON.toJSONString(sendSmsResponse));
        } catch (TeaException error) {
            // 如有需要，请打印 error
            com.aliyun.teautil.Common.assertAsString(error.message);
            log.error("调用发送短信接口失败：{}", error.toString());
            return AjaxResult.error(error.toString(), "发送短信失败");
        } catch (Exception _error) {
            TeaException error = new TeaException(_error.getMessage(), _error);
            // 如有需要，请打印 error
            com.aliyun.teautil.Common.assertAsString(error.message);
            log.error("调用发送短信接口失败：{}", error.toString());
            return AjaxResult.error(error.toString(), "发送短信失败");
        }
        return AjaxResult.success(new Gson().toJson(sendSmsResponse.body));
    }

    /**
     * 批量发送短信接口
     *  如需在一次请求中分别向多个不同的手机号码发送不同签名和模板内容的短信
     *
     * @param tempCode 短信模板CODE
     * @param tempParams 短信模板变量对应的实际值，JSON 数组格式，eg：[{"code":"1234"},{"code":"2345"}]
     * @param phoneNumbers 接收短信的手机号码，JSON 数组格式，eg: ["1590***0000","13500***000"]
     * @throws Exception
     */
    public AjaxResult sendBatchSms(String tempCode, String tempParams, String phoneNumbers) throws Exception {
        // 请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_ID 和 ALIBABA_CLOUD_ACCESS_KEY_SECRET。
        // 工程代码泄露可能会导致 AccessKey 泄露，并威胁账号下所有资源的安全性。以下代码示例使用环境变量获取 AccessKey 的方式进行调用，仅供参考，建议使用更安全的 STS 方式，更多鉴权访问方式请参见：https://help.aliyun.com/document_detail/378657.html
//        com.aliyun.dysmsapi20170525.Client client = createClient(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"), System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
        com.aliyun.dysmsapi20170525.Client client = createClient(alibabaCloudAccessKeyId, alibabaCloudAccessKeySecret);
        com.aliyun.dysmsapi20170525.models.SendBatchSmsRequest sendBatchSmsRequest = new com.aliyun.dysmsapi20170525.models.SendBatchSmsRequest();
        // 接收短信的手机号码，JSON 数组格式，eg: ["1590***0000","13500***000"]
        sendBatchSmsRequest.setPhoneNumberJson(phoneNumbers);
        // 短信签名名称，JSON 数组格式，eg: ["阿里云","阿里巴巴"]
        sendBatchSmsRequest.setSignNameJson("");
        // 短信模板CODE
        sendBatchSmsRequest.setTemplateCode(tempCode);
        // 短信模板变量对应的实际值，JSON 数组格式，eg：[{"code":"1234"},{"code":"2345"}]
        sendBatchSmsRequest.setTemplateParamJson(tempParams);
        com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
        SendBatchSmsResponse sendBatchSmsResponse;
        try {
            log.info("调用发送短信接口请求参数：{}", JSON.toJSONString(sendBatchSmsRequest));
            // 复制代码运行请自行打印 API 的返回值
            sendBatchSmsResponse = client.sendBatchSmsWithOptions(sendBatchSmsRequest, runtime);
            log.info("调用发送短信接口返回结果：{}", JSON.toJSONString(sendBatchSmsResponse));
        } catch (TeaException error) {
            // 如有需要，请打印 error
            com.aliyun.teautil.Common.assertAsString(error.message);
            log.error("调用发送短信接口失败：{}", error.toString());
            return AjaxResult.error(error.toString(), "发送短信失败");
        } catch (Exception _error) {
            TeaException error = new TeaException(_error.getMessage(), _error);
            // 如有需要，请打印 error
            com.aliyun.teautil.Common.assertAsString(error.message);
            log.error("调用发送短信接口失败：{}", error.toString());
            return AjaxResult.error(error.toString(), "发送短信失败");
        }
        return AjaxResult.success(new Gson().toJson(sendBatchSmsResponse.body));
    }

}
